from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, Path
from sqlalchemy.orm import Session
from sqlalchemy import and_
import json

from database.db import get_db
from models.task_scenario import TaskScenario
from models.detection_target import DetectionTarget
from schemas.task_scenario import (
    TaskScenarioSchema, TaskScenarioCreate, TaskScenarioUpdate,
    TaskScenarioList, TaskScenarioWithTemplate, CloneScenarioRequest
)
from api.deps import get_current_user
from models.user import User

router = APIRouter()


@router.get("/", response_model=TaskScenarioList)
async def get_task_scenarios(
    name: Optional[str] = Query(None, description="场景名称搜索"),
    scenario_type: Optional[str] = Query(None, description="场景类型：preset/custom"),
    is_active: Optional[bool] = Query(None, description="是否激活"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页大小"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务场景列表"""
    query = db.query(TaskScenario)
    
    # 构建查询条件
    if name:
        query = query.filter(TaskScenario.name.contains(name))
    if scenario_type:
        query = query.filter(TaskScenario.scenario_type == scenario_type)
    if is_active is not None:
        query = query.filter(TaskScenario.is_active == is_active)
    
    # 计算总数
    total = query.count()
    
    # 分页查询
    offset = (page - 1) * page_size
    scenarios = query.offset(offset).limit(page_size).all()
    
    # 转换为响应模型
    scenario_schemas = []
    for scenario in scenarios:
        scenario_dict = {
            "id": scenario.id,
            "name": scenario.name,
            "description": scenario.description,
            "scenario_type": scenario.scenario_type,
            "drone_type_requirements": json.loads(scenario.drone_type_requirements) if scenario.drone_type_requirements else None,
            "detection_targets": [
                {
                    "id": target.id,
                    "name": target.name,
                    "target_type": target.target_type,
                    "properties": json.loads(target.properties) if target.properties else None
                }
                for target in scenario.detection_target_objects
            ],
            "default_route_logic": json.loads(scenario.default_route_logic) if scenario.default_route_logic else None,
            "detection_model_ids": json.loads(scenario.detection_model_ids) if scenario.detection_model_ids else None,
            "permission_config": json.loads(scenario.permission_config) if scenario.permission_config else None,
            "created_from_template_id": scenario.created_from_template_id,
            "is_active": scenario.is_active,
            "created_at": scenario.created_at,
            "updated_at": scenario.updated_at
        }
        scenario_schemas.append(TaskScenarioSchema(**scenario_dict))
    
    return TaskScenarioList(
        items=scenario_schemas,
        total=total,
        page=page,
        page_size=page_size
    )


@router.get("/preset-templates", response_model=List[TaskScenarioSchema])
async def get_preset_templates(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取预设场景模板列表"""
    templates = db.query(TaskScenario).filter(
        and_(
            TaskScenario.scenario_type == "preset",
            TaskScenario.is_active == True
        )
    ).all()
    
    # 转换为响应模型
    template_schemas = []
    for template in templates:
        template_dict = {
            "id": template.id,
            "name": template.name,
            "description": template.description,
            "scenario_type": template.scenario_type,
            "drone_type_requirements": json.loads(template.drone_type_requirements) if template.drone_type_requirements else None,
            "detection_targets": [
                {
                    "id": target.id,
                    "name": target.name,
                    "target_type": target.target_type,
                    "properties": json.loads(target.properties) if target.properties else None
                }
                for target in template.detection_target_objects
            ],
            "default_route_logic": json.loads(template.default_route_logic) if template.default_route_logic else None,
            "detection_model_ids": json.loads(template.detection_model_ids) if template.detection_model_ids else None,
            "permission_config": json.loads(template.permission_config) if template.permission_config else None,
            "created_from_template_id": template.created_from_template_id,
            "is_active": template.is_active,
            "created_at": template.created_at,
            "updated_at": template.updated_at
        }
        template_schemas.append(TaskScenarioSchema(**template_dict))
    
    return template_schemas


@router.get("/{scenario_id}", response_model=TaskScenarioWithTemplate)
async def get_task_scenario(
    scenario_id: int = Path(..., description="场景ID"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """获取任务场景详情"""
    scenario = db.query(TaskScenario).filter(TaskScenario.id == scenario_id).first()
    if not scenario:
        raise HTTPException(status_code=404, detail="场景不存在")
    
    # 构建基本响应数据
    scenario_dict = {
        "id": scenario.id,
        "name": scenario.name,
        "description": scenario.description,
        "scenario_type": scenario.scenario_type,
        "drone_type_requirements": json.loads(scenario.drone_type_requirements) if scenario.drone_type_requirements else None,
        "detection_targets": [
            {
                "id": target.id,
                "name": target.name,
                "target_type": target.target_type,
                "properties": json.loads(target.properties) if target.properties else None
            }
            for target in scenario.detection_target_objects
        ],
        "default_route_logic": json.loads(scenario.default_route_logic) if scenario.default_route_logic else None,
        "detection_model_ids": json.loads(scenario.detection_model_ids) if scenario.detection_model_ids else None,
        "permission_config": json.loads(scenario.permission_config) if scenario.permission_config else None,
        "created_from_template_id": scenario.created_from_template_id,
        "is_active": scenario.is_active,
        "created_at": scenario.created_at,
        "updated_at": scenario.updated_at
    }
    
    # 添加模板信息
    created_from_template = None
    if scenario.created_from_template:
        template_dict = {
            "id": scenario.created_from_template.id,
            "name": scenario.created_from_template.name,
            "description": scenario.created_from_template.description,
            "scenario_type": scenario.created_from_template.scenario_type,
            "drone_type_requirements": json.loads(scenario.created_from_template.drone_type_requirements) if scenario.created_from_template.drone_type_requirements else None,
            "detection_targets": [
                {
                    "id": target.id,
                    "name": target.name,
                    "target_type": target.target_type,
                    "properties": json.loads(target.properties) if target.properties else None
                }
                for target in scenario.created_from_template.detection_target_objects
            ],
            "default_route_logic": json.loads(scenario.created_from_template.default_route_logic) if scenario.created_from_template.default_route_logic else None,
            "detection_model_ids": json.loads(scenario.created_from_template.detection_model_ids) if scenario.created_from_template.detection_model_ids else None,
            "permission_config": json.loads(scenario.created_from_template.permission_config) if scenario.created_from_template.permission_config else None,
            "created_from_template_id": scenario.created_from_template.created_from_template_id,
            "is_active": scenario.created_from_template.is_active,
            "created_at": scenario.created_from_template.created_at,
            "updated_at": scenario.created_from_template.updated_at
        }
        created_from_template = TaskScenarioSchema(**template_dict)
    
    return TaskScenarioWithTemplate(
        **scenario_dict,
        created_from_template=created_from_template
    )


@router.post("/", response_model=TaskScenarioSchema)
async def create_task_scenario(
    scenario_data: TaskScenarioCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """创建任务场景"""
    # 检查是否基于模板创建
    if scenario_data.created_from_template_id:
        template = db.query(TaskScenario).filter(
            TaskScenario.id == scenario_data.created_from_template_id
        ).first()
        if not template:
            raise HTTPException(status_code=404, detail="模板不存在")
    
    # 创建新场景
    new_scenario = TaskScenario(
        name=scenario_data.name,
        description=scenario_data.description,
        scenario_type="custom",  # 创建的都是自定义场景
        drone_type_requirements=json.dumps(scenario_data.drone_type_requirements) if scenario_data.drone_type_requirements else None,
        default_route_logic=json.dumps(scenario_data.default_route_logic) if scenario_data.default_route_logic else None,
        detection_model_ids=json.dumps(scenario_data.detection_model_ids) if scenario_data.detection_model_ids else None,
        permission_config=json.dumps(scenario_data.permission_config) if scenario_data.permission_config else None,
        created_from_template_id=scenario_data.created_from_template_id,
        is_active=scenario_data.is_active
    )
    
    # 关联检测目标
    if scenario_data.detection_target_ids:
        targets = db.query(DetectionTarget).filter(DetectionTarget.id.in_(scenario_data.detection_target_ids)).all()
        new_scenario.detection_target_objects = targets
    
    db.add(new_scenario)
    db.commit()
    db.refresh(new_scenario)
    
    # 返回响应
    return TaskScenarioSchema(
        id=new_scenario.id,
        name=new_scenario.name,
        description=new_scenario.description,
        scenario_type=new_scenario.scenario_type,
        drone_type_requirements=json.loads(new_scenario.drone_type_requirements) if new_scenario.drone_type_requirements else None,
        detection_target_ids=scenario_data.detection_target_ids,
        default_route_logic=scenario_data.default_route_logic,
        detection_model_ids=scenario_data.detection_model_ids,
        permission_config=scenario_data.permission_config,
        created_from_template_id=new_scenario.created_from_template_id,
        is_active=new_scenario.is_active,
        created_at=new_scenario.created_at,
        updated_at=new_scenario.updated_at,
        # detection_targets will be populated from detection_target_objects relationship
    )


@router.post("/{scenario_id}/clone", response_model=TaskScenarioSchema)
async def clone_task_scenario(
    scenario_id: int = Path(..., description="要复制的场景ID"),
    clone_data: CloneScenarioRequest = ...,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """复制任务场景"""
    # 获取原场景
    original_scenario = db.query(TaskScenario).filter(
        TaskScenario.id == scenario_id
    ).first()
    if not original_scenario:
        raise HTTPException(status_code=404, detail="场景不存在")
    
    # 创建新场景
    new_scenario = TaskScenario(
        name=clone_data.name,
        description=clone_data.description if clone_data.description else original_scenario.description,
        scenario_type="custom",  # 复制的都是自定义场景
        drone_type_requirements=original_scenario.drone_type_requirements,
        default_route_logic=original_scenario.default_route_logic,
        detection_model_ids=original_scenario.detection_model_ids,
        permission_config=original_scenario.permission_config,
        created_from_template_id=original_scenario.id,
        is_active=original_scenario.is_active
    )
    
    # 复制检测目标关联
    new_scenario.detection_target_objects = original_scenario.detection_target_objects.copy()
    
    db.add(new_scenario)
    db.commit()
    db.refresh(new_scenario)
    
    # 返回响应
    return TaskScenarioSchema(
        id=new_scenario.id,
        name=new_scenario.name,
        description=new_scenario.description,
        scenario_type=new_scenario.scenario_type,
        drone_type_requirements=json.loads(new_scenario.drone_type_requirements) if new_scenario.drone_type_requirements else None,
        detection_targets=[
            {
                "id": target.id,
                "name": target.name,
                "target_type": target.target_type,
                "properties": json.loads(target.properties) if target.properties else None
            }
            for target in new_scenario.detection_target_objects
        ],
        default_route_logic=json.loads(new_scenario.default_route_logic) if new_scenario.default_route_logic else None,
        detection_model_ids=json.loads(new_scenario.detection_model_ids) if new_scenario.detection_model_ids else None,
        permission_config=json.loads(new_scenario.permission_config) if new_scenario.permission_config else None,
        created_from_template_id=new_scenario.created_from_template_id,
        is_active=new_scenario.is_active,
        created_at=new_scenario.created_at,
        updated_at=new_scenario.updated_at
    )


@router.put("/{scenario_id}", response_model=TaskScenarioSchema)
async def update_task_scenario(
    scenario_id: int = Path(..., description="场景ID"),
    scenario_data: TaskScenarioUpdate = ...,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """更新任务场景"""
    # 获取场景
    scenario = db.query(TaskScenario).filter(TaskScenario.id == scenario_id).first()
    if not scenario:
        raise HTTPException(status_code=404, detail="场景不存在")
    
    # 允许编辑预设模板
    pass
    
    # 更新字段
    update_data = scenario_data.model_dump(exclude_unset=True)
    
    for field, value in update_data.items():
        if field == "detection_target_ids":
            # 处理检测目标关联
            if value is not None:
                targets = db.query(DetectionTarget).filter(DetectionTarget.id.in_(value)).all()
                scenario.detection_target_objects = targets
            else:
                scenario.detection_target_objects = []
        elif field in ["drone_type_requirements", "default_route_logic", "permission_config"]:
            # 处理JSON字段
            if value is not None:
                setattr(scenario, field, json.dumps(value))
            else:
                setattr(scenario, field, None)
        elif field == "detection_model_ids":
            # 处理模型ID列表
            if value is not None:
                setattr(scenario, field, json.dumps(value))
            else:
                setattr(scenario, field, None)
        else:
            setattr(scenario, field, value)
    
    db.commit()
    db.refresh(scenario)
    
    # 返回响应
    return TaskScenarioSchema(
        id=scenario.id,
        name=scenario.name,
        description=scenario.description,
        scenario_type=scenario.scenario_type,
        drone_type_requirements=json.loads(scenario.drone_type_requirements) if scenario.drone_type_requirements else None,
        detection_targets=[
            {
                "id": target.id,
                "name": target.name,
                "target_type": target.target_type,
                "properties": json.loads(target.properties) if target.properties else None
            }
            for target in scenario.detection_target_objects
        ],
        default_route_logic=json.loads(scenario.default_route_logic) if scenario.default_route_logic else None,
        detection_model_ids=json.loads(scenario.detection_model_ids) if scenario.detection_model_ids else None,
        permission_config=json.loads(scenario.permission_config) if scenario.permission_config else None,
        created_from_template_id=scenario.created_from_template_id,
        is_active=scenario.is_active,
        created_at=scenario.created_at,
        updated_at=scenario.updated_at
    )


@router.delete("/{scenario_id}")
async def delete_task_scenario(
    scenario_id: int = Path(..., description="场景ID"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """删除任务场景"""
    # 获取场景
    scenario = db.query(TaskScenario).filter(TaskScenario.id == scenario_id).first()
    if not scenario:
        raise HTTPException(status_code=404, detail="场景不存在")
    
    # 预设模板不允许删除
    if scenario.scenario_type == "preset":
        raise HTTPException(status_code=403, detail="预设模板不允许删除")
    
    # 检查是否有衍生场景
    derived_scenarios = db.query(TaskScenario).filter(
        TaskScenario.created_from_template_id == scenario_id
    ).count()
    
    if derived_scenarios > 0:
        raise HTTPException(status_code=400, detail=f"该场景有{derived_scenarios}个衍生场景，无法删除")
    
    # 删除场景
    db.delete(scenario)
    db.commit()
    
    return {"message": "删除成功"}